package com.stephen.redisdemo.atomic;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author: stephen
 * @create: 2020-02-28 15:51
 * @description:
 */
public class AtomicRefenceDemo {

    public static void main(String[] args) throws InterruptedException {

        System.out.println("--------ABA问题的产生---------");

        AtomicReference<Integer> integerAtomicReference = new AtomicReference<>(100);
        Thread t1 = new Thread(() -> {
            integerAtomicReference.compareAndSet(100, 101);
            integerAtomicReference.compareAndSet(101, 100);
        });

        Thread t2 = new Thread(() -> {
            boolean b = integerAtomicReference.compareAndSet(100, 2020);
            System.out.println(b + "\t" + integerAtomicReference.get());
        });
        t1.join();
        t1.start();
        t2.join();
        t2.start();

        TimeUnit.SECONDS.sleep(1);
        System.out.println("-----------ABA问题的解决---------------");
        // t3,t4初始版本号相同,在各自的版本号上做操作
        AtomicStampedReference atomicStampedReference = new AtomicStampedReference(100,1);
        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() +"第一次版本号为: " + atomicStampedReference.getStamp());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            atomicStampedReference.compareAndSet(100, 101,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName() +"第2次版本号为: " + atomicStampedReference.getStamp());
            atomicStampedReference.compareAndSet(101, 100,atomicStampedReference.getStamp(),atomicStampedReference.getStamp()+1);
            System.out.println(Thread.currentThread().getName() +"第3次版本号为: " + atomicStampedReference.getStamp());
        },"t3").start();

        new Thread(() -> {
            int stamp = atomicStampedReference.getStamp();
            try {
                System.out.println(Thread.currentThread().getName() +"第一次版本号为: " + stamp);
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            boolean b = atomicStampedReference.compareAndSet(100, 2020, stamp, stamp + 1);
            System.out.println(b + "\t" + atomicStampedReference.getReference());

        },"t4").start();




    }

}
